package com.base.api.pubg.impl;

import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.base.api.pubg.IPubgDataService;
import com.base.api.pubg.crawl.DownloadData;
import com.base.api.pubg.enums.SERVER;
import com.base.dao.pubg.JsondataMapper;
import com.base.dao.pubg.LogitemunequipMapper;
import com.base.dao.pubg.LogplayerpositionMapper;
import com.base.utils.ResultUtil;
import com.base.utils.enums.RESULT_CODE;
import com.base.vo.pubg.Jsondata;
import com.base.vo.pubg.Logitemunequip;
import com.base.vo.pubg.Logplayerposition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * PUBG数据服务
 *
 * @author: junw
 * @date: 2018/5/17 11:43
 */
@Service
public class PubgDataServiceImpl implements IPubgDataService {

    private Logger logger = LoggerFactory.getLogger(getClass());

    private LogitemunequipMapper logitemunequipMapper;

    private LogplayerpositionMapper logplayerpositionMapper;

    private JsondataMapper jsondataMapper;

    private DownloadData downloadData;

    @Autowired
    public PubgDataServiceImpl(LogitemunequipMapper logitemunequipMapper, LogplayerpositionMapper logplayerpositionMapper, JsondataMapper jsondataMapper, DownloadData downloadData) {
        this.logitemunequipMapper = logitemunequipMapper;
        this.logplayerpositionMapper = logplayerpositionMapper;
        this.jsondataMapper = jsondataMapper;
        this.downloadData = downloadData;
    }

    @Override
    public JSONArray getTelemetry(String displayWidth, String matchId) {
        Logitemunequip condition = new Logitemunequip();
        condition.setItemItemid("Item_Back_B_01_StartParachutePack_C");
        condition.setCommonMatchid(matchId);
        List<Logitemunequip> logitemunequipList = logitemunequipMapper.selectBySelective(condition);
        JSONArray jsonArray = new JSONArray();
        JSONArray subJsonArray;
        for (Logitemunequip logitemunequip : logitemunequipList) {
            subJsonArray = new JSONArray();
            subJsonArray.add(getSuitableSize(logitemunequip.getCharacterLocationX(), displayWidth));
            subJsonArray.add(getSuitableSize(logitemunequip.getCharacterLocationY(), displayWidth));
            jsonArray.add(subJsonArray);
        }
        return jsonArray;
    }

    @Override
    public JSONArray getPosition(String displayWidth, String matchId, String name) {
        Logitemunequip itemunequipCondition = new Logitemunequip();
        itemunequipCondition.setItemItemid("Item_Back_B_01_StartParachutePack_C");
        itemunequipCondition.setCharacterName(name);
        itemunequipCondition.setCommonMatchid(matchId);
        List<Logitemunequip> logitemunequipList = logitemunequipMapper.selectBySelective(itemunequipCondition);
        String landTime = logitemunequipList.get(0).getD();

        Logplayerposition condition = new Logplayerposition();
        condition.setCommonMatchid(matchId);
        condition.setCharacterName(name);
        condition.setD(landTime);
        List<Logplayerposition> logplayerpositionList = logplayerpositionMapper.selectBySelective(condition);
        JSONArray jsonArray = new JSONArray();
        JSONArray subJsonArray;
        for (Logplayerposition logplayerposition : logplayerpositionList) {
            subJsonArray = new JSONArray();
            subJsonArray.add(getSuitableSize(logplayerposition.getCharacterLocationX(), displayWidth));
            subJsonArray.add(getSuitableSize(logplayerposition.getCharacterLocationY(), displayWidth));
            jsonArray.add(subJsonArray);
        }
        return jsonArray;
    }

    @Override
    public String getAllPosition(String displayWidth, String matchId) {
        JSONArray point = new JSONArray();
        JSONArray lines = new JSONArray();
        for (String name : logplayerpositionMapper.selectAllName(matchId)){
            Logitemunequip itemunequipCondition = new Logitemunequip();
            itemunequipCondition.setItemItemid("Item_Back_B_01_StartParachutePack_C");
            itemunequipCondition.setCharacterName(name);
            itemunequipCondition.setCommonMatchid(matchId);
            List<Logitemunequip> logitemunequipList = logitemunequipMapper.selectBySelective(itemunequipCondition);
            if(logitemunequipList.size() < 1){
                continue;
            }
            String landTime = logitemunequipList.get(0).getD();

            Logplayerposition condition = new Logplayerposition();
            condition.setCommonMatchid(matchId);
            condition.setCharacterName(name);
            condition.setD(landTime);
            List<Logplayerposition> logplayerpositionList = logplayerpositionMapper.selectBySelective(condition);
            JSONArray array = new JSONArray();
            JSONArray subJsonArray;
            if(logplayerpositionList.size() > 0){
                Logplayerposition first = logplayerpositionList.get(0);
                JSONArray firstArray = new JSONArray();
                firstArray.add(getSuitableSize(first.getCharacterLocationX(), displayWidth));
                firstArray.add(getSuitableSize(first.getCharacterLocationY(), displayWidth));
                point.add(firstArray);
            }
            for (Logplayerposition logplayerposition : logplayerpositionList) {
                subJsonArray = new JSONArray();
                subJsonArray.add(getSuitableSize(logplayerposition.getCharacterLocationX(), displayWidth));
                subJsonArray.add(getSuitableSize(logplayerposition.getCharacterLocationY(), displayWidth));
                array.add(subJsonArray);
            }
            lines.add(array);
        }
        return "[".concat(point.toJSONString()).concat(",").concat(lines.toJSONString()).concat("]");
    }

    @Override
    public String starDownloader(String server, int threadCount, String... names) {
        if(downloadData.isWork()){
            return ResultUtil.error(RESULT_CODE.WAIT.getCode(), "正在下载中...");
        }
        downloadData.getDownloadConfig().init();
        downloadData.getDownloadConfig().setNameArray(names);
        downloadData.getDownloadConfig().setThreadCount(threadCount);
        downloadData.getDownloadConfig().getPubgHttpClient().setServerCode(server);
        return downloadData.run();
    }

    @Override
    public JSONArray getServerList() {
        JSONArray jsonArray = new JSONArray();
        SERVER[] servers = SERVER.values();
        for(int i = 0; i < servers.length; i++){
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("id", i);
            jsonObject.put("text", servers[i].getServerName());
            if(StringUtils.equals(jsonObject.getString("text"), "pc-as")){
                jsonObject.put("selected", true);
            }
            jsonArray.add(jsonObject);
        }
        return jsonArray;
    }

    @Override
    public JSONObject heartbeat() {
        JSONObject downloaderInfo = downloadData.getDownloaderInfo();
        getProgress(downloaderInfo);
        return downloaderInfo;
    }

    @Override
    public String close() {
        if(!downloadData.isWork()){
            return ResultUtil.success("下载器未启动！");
        }
        if(downloadData.getDownloadConfig().isClose()){
            return ResultUtil.success("下载器已停止！");
        }else{
            downloadData.getDownloadConfig().setClose(true);
            return ResultUtil.success("下载器正在停止，请等待线程销毁！");
        }
    }

    @Override
    public String querymatch(String name, String server, String startdate, String enddate) {
        List<Jsondata> jsondataList = jsondataMapper.selectNoLontText(name, server, startdate, enddate);
        return JSON.toJSON(jsondataList).toString();
    }

    /**
     * 计算实际页面显示值
     *
     * @param original
     * @param displayWidth
     * @return
     */
    private String getSuitableSize(String original, String displayWidth) {
        return new BigDecimal(original).divide(new BigDecimal("816000"), 4, BigDecimal.ROUND_HALF_UP)
                .multiply(new BigDecimal(displayWidth)).setScale(0, BigDecimal.ROUND_HALF_UP).toString();
    }


    /**
     * 当前进度
     *
     * @param downloaderInfo
     */
    private void getProgress(JSONObject downloaderInfo) {
        Map<String, Object> info = new HashMap<>(16);
        info.put("总数:", downloadData.allSeed);
        info.put("完成数:", downloadData.allSeed - downloadData.getDownloadConfig().waitingForDownload());
        info.put("剩余数:", downloadData.getDownloadConfig().waitingForDownload());
        info.put("启动线程数:", downloadData.getDownloadConfig().getThreadCount());
        info.put("当前线程数:", downloadData.getDownloadConfig().getCurrentThreadCount());
        getProgressInfo(downloaderInfo, info);
        downloaderInfo.put("all", downloadData.allSeed);
        downloaderInfo.put("remain", downloadData.getDownloadConfig().waitingForDownload());
        downloaderInfo.put("working", !downloadData.getDownloadConfig().isClose());
    }

    /**
     * 当前下载信息
     *
     * @param downloaderInfo
     * @param info
     */
    private void getProgressInfo(JSONObject downloaderInfo, Map<String, Object> info) {
        JSONArray jsonArray = new JSONArray();
        JSONObject jsonObject = new JSONObject();
        for (String key : info.keySet()){
            JSONObject object = new JSONObject();
            object.put("name", key);
            object.put("value", info.get(key));
            jsonArray.add(object);
        }
        jsonObject.put("total", jsonArray.size());
        jsonObject.put("rows", jsonArray);
        downloaderInfo.put("data", jsonObject);
    }

}
